#ifndef FATFS_H
#define FATFS_H

#include "mutex.h"

#pragma pack(1)
typedef struct _dbr_t{
    /*
    uint8_t BS_jmpBoot[3];//jmp to boot code,jmpBoot[0]=0xEb,jmpBoot[1]=0x??,jmpBoot=0x90
    uint8_t BS_OEMName[8];//adviced MSWIN4.1, just a char*
    uint16_t BPB_BytesPerSec;//bytes per sector,512,1024,2048,4096
    uint8_t BPB_SecPerClus; //sectors per cluster. 1,2,4,8,16,...
    uint16_t BPB_RsvdSecCnt;//total sectors in reserved area
    uint8_t BPB_NumFATS; //2 usually,the num of fats in the volume
    uint16_t BPB_RootEntCnt; //should be 512. the num of dirs in the root dir, every item is 32bytes
    uint16_t BPB_TotSec16; //for fat12 and fat16, total sectors in the 4 basic part
    uint8_t BPB_Media;//not portable, 0x80, portable 0xF0
    uint16_t BPB_FATSz16; //sectors a FAT Table occupied
    uint16_t SecPerTrk;
    uint16_t BPB_NumHeads;
    uint32_t BPB_HiddSec;
    uint32_t BPB_TotSec32;*/
    uint8_t BS_jmpBoot[3];                 // 跳转代码 EB 3C 90
    uint8_t BS_OEMName[8];                 // OEM名称 MSDOS.1
    uint16_t BPB_BytsPerSec;               // 每扇区字节数 512
    uint8_t BPB_SecPerClus;                // 每簇扇区数 2
    uint16_t BPB_RsvdSecCnt;               // 保留区扇区数 2
    uint8_t BPB_NumFATs;                   // FAT表项数 2
    uint16_t BPB_RootEntCnt;               // 根目录项目数 512
    uint16_t BPB_TotSec16;                 // 总的扇区数 under32M 0
    uint8_t BPB_Media;                     // 媒体类型 f8
    uint16_t BPB_FATSz16;                  // FAT表项大小 199
    uint16_t BPB_SecPerTrk;                // 每磁道扇区数 sectors per track 63
    uint16_t BPB_NumHeads;                 // 磁头数 255
    uint32_t BPB_HiddSec;                  // 隐藏扇区数 128
    uint32_t BPB_TotSec32;                 // 总的扇区数 102272

	uint8_t BS_DrvNum;                     // 磁盘驱动器参数 80
	uint8_t BS_Reserved1;				   // 保留字节 0
	uint8_t BS_BootSig;                    // 扩展引导标记 boot signature 29
	uint32_t BS_VolID;                     // 卷标序号 volume serial number
	uint8_t BS_VolLab[11];                 // 磁盘卷标
	uint8_t BS_FileSysType[8];             // 文件类型名称
}dbr_t;

//32bytes
typedef struct _diritem_t{
    uint8_t DIR_Name[11];               //filename+externsion
    uint8_t DIR_Attr;
    uint8_t DIR_NTRes;
    uint8_t DIR_CrtTimeTeenth;
    uint16_t DIR_CrtTime;
    uint16_t DIR_CrtDate;
    uint16_t DIR_LastAccDate;
    uint16_t DIR_FstClusHI;  // 簇号高16位
    uint16_t DIR_WrtTime;
    uint16_t DIR_WrtDate;
    uint16_t DIR_FstClusLO;
    uint32_t DIR_FileSize;   // 文件字节大小
}diritem_t;
#pragma pack()
#define CLUSTER_FAT_FREE       0
#define DIRITEM_ATTR_READ_ONLY 0x01
#define DIRITEM_ATTR_HIDDEN    0x02
#define DIRITEM_ATTR_SYSTEM    0x04
#define DIRITEM_ATTR_VOLUME_ID 0x08
#define DIRITEM_ATTR_DIRECTORY 0x10
#define DIRITEM_ATTR_ARCHIVE   0x20
//#define DIRITEM_ATTR_LONG_NAME (DIRITEM_ATTR_READ_ONLY | DIRITEM_ATTR_HIDDEN | DIRITEM_ATTR_SYSTEM | DIRITEM_ATTR_VOLUME_ID)
#define DIRITEM_ATTR_LONG_NAME 0x0F

#define DIRITEM_NAME_FREE      0xE5
#define DIRITEM_NAME_END       0x00

#define FAT_CLUSTER_INVALID    0xFFF8

typedef struct _fat_t{
     // fat文件系统本身信息
    uint32_t tbl_start;                     // FAT表起始扇区号
    uint32_t tbl_cnt;                       // FAT表数量
    uint32_t tbl_sectors;                   // 每个FAT表的扇区数
    uint32_t bytes_per_sec;                 // 每扇区大小
    uint32_t sec_per_cluster;               // 每簇的扇区数
    uint32_t root_ent_cnt;                  // 根目录的项数
    uint32_t root_start;                    // 根目录起始扇区号
    uint32_t data_start;                    // 数据区起始扇区号
    uint32_t cluster_byte_size;             // 每簇字节数

    // 与文件系统读写相关信息
    uint8_t * fat_buffer;             		// FAT表项缓冲,should only be used when read disk
    int curr_sector;                        // 当前缓存的扇区数

    struct _fs_t * fs;                      // 所在的文件系统
    mutex_t mutex;                          // 互斥信号量
}fat_t;

typedef uint16_t cluster_t;
#define SFN_LEN    11
#endif